/**
 * Liscense: 	GPL http://www.gnu.org/copyleft/gpl.html
 * By: 		A. Tres Finocchiaro
 * Date:	2007
 * Java:	6.0SE
 */

/**
 *
 * @author Tres Finocchiaro
 * @author Steve Kurilovitch
 */

package com.pentajock.docdb;

import java.io.*;
import java.awt.*;
import java.sql.*;
import javax.swing.*;
import javax.swing.UIManager.*;

import com.pentajock.docdb.database.DBController;
import com.pentajock.docdb.dialogs.Dialogs;
import com.pentajock.docdb.utils.*;


/**
 * The Main class that is used to run the application.
 */
public class Main {
	static public final String DEFAULT_TITLE = "Document Database";
	/*static public final String[] FILE_SERVERS = {
		"file://///appsrv2/Turnover/Shared%20Documents/",
		"file://///hdscansvr/scan/SecurityApps06/",
		"file://///hdscansvr/scan/SecurityApps07", 
		"file://///hdscansvr/scan/Request%20for%20Support%2007/"};*/
	static public final String VERSION_NUMBER = "1.1.1";
	// Shows database debug messages.
	static private boolean isDebugMode;
	// Supress class name for multi-part debug messages
	static private boolean debugSwitch = false;
	static public QuickIni sysIni;
	static public QuickIni userIni;
	// The window that the user will be interacting with
	private ClientWindow window;
	
	public Main() {
		printDebug("Program initialized.");
		window = new ClientWindow();
		printDebug("Window initialized.");
	}
	
	static public void main(String[] args) {
		if (!Utils.processArgs(args)) return;
		try {
			System.setErr(new PrintStream(new BufferedOutputStream(new FileOutputStream("errLog.txt", false)), true));
		}
		catch(FileNotFoundException ex) {
			printStackTrace(ex, "Could not open errLog.txt");
		}
		
		Utils.setLookAndFeel(
			userIni.getStringProperty("User Interface", "l&f"),
			userIni.getBooleanProperty("User Interface", "decorated")
		);
		String url = sysIni.getStringProperty("HSQL Database", "url");
		String driver = "org.hsqldb.jdbcDriver";
                Toolkit.getDefaultToolkit().setDynamicLayout(true);
		try {
                    //connectToDatabase(String driver, String database, String name, String pw);
			if(DBController.connectToDatabase(driver, url, "SA", "")) {
				SwingUtilities.invokeLater(new Runnable() {
					public void run() {
						Main app = new Main();
						app.go();
					}
				});
			}
			else {
				if (Dialogs.showConfirm(url, "Database couldn't be found at the specified location.  Create a test/internal database?")) {
					if (DBController.createInternalDatabase()) {
						SwingUtilities.invokeLater(new Runnable() {
							public void run() {
								Main app = new Main();
								app.go();
							}
						});
					}
					else
						System.exit(0);
				}
				else {
					//Dialogs.showError("Connection to database failed.");
					System.exit(0);
				}
			}
		}
		//catch(SQLException ex) {
		//	printStackTrace(ex, "Exception connecting to database");
		//}
                catch(SQLException sql) {
			Dialogs.showError(sql, "SQL Error loading program");
                        System.exit(0);
                }
                catch(ClassNotFoundException cnf) {
                        Dialogs.showError(cnf, "HSQL JDBC driver not found");
                        System.exit(0);
                }
                catch(IOException io) {
                        Dialogs.showError(io, "Error copying data folder from Jar");
                        System.exit(0);
                }
                catch (Exception e) {
                        Dialogs.showError(e, "Generic exception thrown");
                        System.exit(0);
                }
	}
	
	public void go() {
		window.setVisible(true);
	}
	
	/**
	 * c -> Component to change the cursor for.
	 * cursorType -> one of the available Cursor fields
	 *				 defined in the Cursor class
	 */
	static public void setCursor(Component c, int cursorType) {
		setCursor(c, Cursor.getPredefinedCursor(cursorType));
	}
	
	static public void setCursor(Component c, Cursor cursor) {
		c.setCursor(cursor);
	}
	
	static public boolean isDebugMode() {
		return isDebugMode;
	}
	
	static public void setDebugMode(boolean isDebugMode) {
		Main.isDebugMode = isDebugMode;
	}
	
	static public boolean printStackTrace(Exception e) {
		return printStackTrace(e, "");
	}
	
	/** Debug output formatter */
	static public boolean printStackTrace(Exception e, String tempS) {
		if(isDebugMode()) {
			String divLine = "-------------------------------------------------";
			System.out.println(divLine);
			e.printStackTrace(System.out);
			System.out.println(divLine);
			System.out.println(tempS);
			System.out.println(divLine);
			System.out.println(getCallerClass() + ": Continuing...");

			System.err.println(divLine);
			e.printStackTrace(System.err);
			System.err.println(divLine);
			System.err.println(tempS);
			System.err.println(divLine);
			System.err.println(getCallerClass() + ": Continuing...");
		}
		return false; // Return type added for nesting purposes
	}
	
	/** Print debug messages to console */
	static public void printDebug(String message) {
		if(isDebugMode()) {
			// Strip out any lingering HTML tags
			debugOut(message.replaceAll("\\<.*?\\>",""), Utils.getExtension(getCallerClass()));
		}
	}

	/** Find caller class of message */
	public static String getCallerClass(boolean upperCase) {
		try {
			throw new Exception(); 
		}
		catch (Exception e) {
			if (upperCase) return e.getStackTrace()[2].getClassName().toUpperCase();
			return e.getStackTrace()[2].getClassName();
		}
	}
	
	public static String getCallerClass() {
		return getCallerClass(true);
	}
	
	static private void debugOut(String message, String callerClass) {
		if (!debugSwitch) {
			System.out.print(callerClass.toUpperCase() + ": ");
			System.err.print(callerClass.toUpperCase() + ": ");
		}
		
		/* If message ends with '&' the message won't contain a line-break */
		if (message.endsWith("&")) {
			message = message.substring(0, message.length() - 1);
			debugSwitch = true;	// Next time, DON'T show the linebreak
		}
		else {
			message = message + "\n";
			debugSwitch = false;	// Next time, DO show the line break
		}
		
		System.out.print(message);
		System.err.print(message);
	}
}
